package io.fatmore.web.api;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import io.fatmore.web.BaseController;

import javax.servlet.http.HttpServletRequest;

/**
 * 
 * <b><code>ApiController</code></b>
 * <p>
 * 
 * </p>
 * @author shangkun.lsk@fastmor.com
 * @since ucun-finance
 */
public abstract class ApiController extends BaseController {
	
	final static Logger logger = LoggerFactory.getLogger(ApiController.class);

	@ExceptionHandler({ Exception.class })
	@ResponseBody
	public Object exception(Exception e){
		return this.onException(e);
	}

	/**
	 * @example return ApiResponse.error(this.parseExceptionMessage(e));
	 * @param e
	 * @return
     */
	public abstract Object onException(Exception e);

	/**
	 * 每个api系统独立实现算法。
	 * 
	 *
	 * @param request
	 * @param body
	 * @throws ApiException
	 * @since tcp-console
	 */
	public abstract void validApi(HttpServletRequest request, String body) throws ApiException;
	
	/**
	 * 注入session
	 * 有些系统需要通过api传递的参数进行session会话的虚拟。
	 * 
	 *
	 * @param request
     * @param body
	 * @since ucun-finance
	 */
	public abstract void initSession(HttpServletRequest request, String body);
	
	public abstract boolean hasSession();


	/**
	 * 根据条件返回不同的异常信息
	 * 
	 * @param e
	 * @return
	 */
	public String parseExceptionMessage(Exception e) {
		if (e instanceof ApiException) {
			return e.getMessage();
		}else if (e instanceof MethodArgumentNotValidException) {
		
			MethodArgumentNotValidException err = (MethodArgumentNotValidException) e;
			String message = "";
			for (ObjectError er : err.getBindingResult().getAllErrors()) {
				message += er.getDefaultMessage() + "；";

			}
			return message;
		}

		String message;
		if (!this.isDebugMode()) {
			message = "sorry, system error.";
		} else {
			message = e.getMessage();
		}
		logger.error(message, e);
		return message;
	}
}
